﻿using HirelSeriesH.Tools;
using Sunny.UI;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace HirelSeriesH.Entity
{
    class VGPower
    {
        private string iD;
        /// <summary>
        /// 电源名称
        /// </summary>
        private string powerName;
        /// <summary>
        /// 电压量程
        /// </summary>
        private decimal maxVoltage;
        /// <summary>
        ///电流量程
        /// </summary>
        private decimal maxCurrent;
        /// <summary>
        /// 设定的目标电压
        /// </summary>
        private decimal voltage;
        /// <summary>
        /// 升降压过程中的当前电压
        /// </summary>
        private decimal voltageCurrent;
        /// <summary>
        /// 升压步长
        /// </summary>
        private decimal upStep;
        /// <summary>
        /// 升压间隔
        /// </summary>
        private decimal upInterval;
        /// <summary>
        /// 降压步长
        /// </summary>
        private decimal downStep;
        /// <summary>
        /// 降压间隔
        /// </summary>
        private decimal downInterval;
        /// <summary>
        /// 监控周期
        /// </summary>
        private decimal checkInterval;
        /// <summary>
        /// 电源的实时电压
        /// </summary>
        private decimal realVoltage = 0;
        /// <summary>
        /// 电源的实时电流
        /// </summary>
        private decimal realCurrent = 0;
        /// <summary>
        /// 定时查询电源输出电压和电流
        /// </summary>
        private Timer timerForLowPowerRealVC = new Timer();
        /// <summary>
        /// 保护电阻
        /// </summary>
        private decimal bHDZ;
        /// <summary>
        /// 是否已开启
        /// </summary>
        private bool isOpen;
        /// <summary>
        /// 是否处于升压或降压状态
        /// </summary>
        private bool isUpDown = false;
        /// <summary>
        /// 升压计时器
        /// </summary>
        private Timer timerUp = new Timer();
        /// <summary>
        /// 降压压计时器
        /// </summary>
        private Timer timerDown = new Timer();
        /// <summary>
        /// 通信端口名称
        /// </summary>
        private SerialPort port;

        private decimal fDDY;

        int tempTime = 0;

        private List<UIDoubleUpDown> numList;

        private UIButton buttonAction;

        private System.Windows.Forms.Label label;

        private decimal voltageValue;

        private decimal upStepVal;

        private readonly object CommandLock = new object();

        private readonly object CommandActionLock = new object();

        private Queue CommandsQueue = new Queue();

        private Channel channel;

        private bool listening = false;//是否没有执行完invoke相关操作  

        private bool closing = false;//是否正在关闭串口，执行Application.DoEvents，并阻止再次invoke  

        private bool isRun = true;

        /// <summary>
        /// 是否通信异常
        /// </summary>
        private bool isCommunityError = false;

        private int index = 0;

        /// <summary>
        /// 定时发送电源命令
        /// </summary>
        //private Timer timerToSender = new Timer();

        public VGPower(SerialPort serialPort, int idx)
        {
            port = serialPort;
            Index = idx;

            timerUp.Elapsed += new ElapsedEventHandler(TimerUpTaskLow);
            //设置是执行一次（false）还是一直执行(true)
            timerUp.AutoReset = true;
            //是否执行System.Timers.Timer.Elapsed事件
            timerUp.Enabled = false;

            timerDown.Elapsed += new ElapsedEventHandler(TimerDownTaskLow);
            //设置是执行一次（false）还是一直执行(true)
            timerDown.AutoReset = true;
            //是否执行System.Timers.Timer.Elapsed事件
            timerDown.Enabled = false;

            //查询低压电源
            TimerForLowPowerRealVC.AutoReset = true;
            TimerForLowPowerRealVC.Enabled = false;
            TimerForLowPowerRealVC.Elapsed += new ElapsedEventHandler(timerForLowPowerRealVC_Tick);
            TimerForLowPowerRealVC.Interval = 2000;

            //定时发送USB电源命令
            /*TimerToSender.AutoReset = true;
            TimerToSender.Enabled = false;
            TimerToSender.Elapsed += new ElapsedEventHandler(TimerToSender_Tick);
            TimerToSender.Interval = 500;*/
        }

        public string ID { get => iD; set => iD = value; }
        public string PowerName { get => powerName; set => powerName = value; }
        public decimal Voltage { get => voltage; set => voltage = value; }
        public decimal UpStep { get => upStep; set => upStep = value; }
        public decimal UpInterval { get => upInterval; set => upInterval = value; }
        public decimal DownStep { get => downStep; set => downStep = value; }
        public decimal DownInterval { get => downInterval; set => downInterval = value; }
        public decimal CheckInterval { get => checkInterval; set => checkInterval = value; }
        public decimal BHDZ { get => bHDZ; set => bHDZ = value; }
        public decimal MaxVoltage { get => maxVoltage; set => maxVoltage = value; }
        public decimal MaxCurrent { get => maxCurrent; set => maxCurrent = value; }
        public bool IsOpen { get => isOpen; set => isOpen = value; }
        public decimal VoltageCurrent { get => voltageCurrent; set => voltageCurrent = value; }
        public Timer TimerUp { get => timerUp; set => timerUp = value; }
        public Timer TimerDown { get => timerDown; set => timerDown = value; }
        public bool IsUpDown { get => isUpDown; set => isUpDown = value; }
        public SerialPort Port { get => port; set => port = value; }
        public int TempTime { get => tempTime; set => tempTime = value; }
        public decimal RealVoltage { get => realVoltage; set => realVoltage = value; }
        public decimal RealCurrent { get => realCurrent; set => realCurrent = value; }
        public Timer TimerForLowPowerRealVC { get => timerForLowPowerRealVC; set => timerForLowPowerRealVC = value; }
        public List<UIDoubleUpDown> NumList { get => numList; set => numList = value; }
        public UIButton ButtonAction { get => buttonAction; set => buttonAction = value; }
        public System.Windows.Forms.Label Label { get => label; set => label = value; }
        public decimal VoltageValue { get => voltageValue; set => voltageValue = value; }
        public decimal UpStepVal { get => upStepVal; set => upStepVal = value; }
        internal Channel Channel { get => channel; set => channel = value; }
        //public Timer TimerToSender { get => timerToSender; set => timerToSender = value; }
        public bool Listening { get => listening; set => listening = value; }
        public bool Closing { get => closing; set => closing = value; }
        public bool IsCommunityError { get => isCommunityError; set => isCommunityError = value; }
        public int Index { get => index; set => index = value; }
        public decimal FDDY { get => fDDY; set => fDDY = value; }
        public bool IsRun { get => isRun; set => isRun = value; }

        public void open()
        {
            //开启电源输出
            byte[] commandBuffer = new byte[] { 0xAA, 0x00, 0x21, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x0A };
            EequeueQueue(commandBuffer);
        }

        public void close()
        {
            //关闭电源输出
            byte[] commandBuffer = new byte[] { 0xAA, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCB, 0x0A };
            EequeueQueue(commandBuffer);
        }

        public void setMaxCurrent()
        {
            //获取远程控制权
            byte[] commandBuffer = new byte[] { 0xAA, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCB, 0x0A };
            EequeueQueue(commandBuffer);

            //设置最大电流
            commandBuffer = new byte[] { 0xAA, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A };
            decimal current = maxCurrent * 1000;
            int intCurr = (int)current;
            commandBuffer[3] = byte.Parse((intCurr % 256).ToString());
            commandBuffer[4] = byte.Parse((intCurr / 256).ToString());
            commandBuffer[25] = CheckWorker.PowerCommandsADD(commandBuffer);

            EequeueQueue(commandBuffer);
        }

        public void setVolt(decimal voltage)
        {
            //获取远程控制权
            byte[] commandBuffer = new byte[] { 0xAA, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCB, 0x0A };
            EequeueQueue(commandBuffer);

            //设置电压
            commandBuffer = new byte[] { 0xAA, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A };
            decimal volt = voltage * 1000;
            int intVolt = (int)volt;
            commandBuffer[3] = byte.Parse((intVolt % 65536 % 256).ToString());
            commandBuffer[4] = byte.Parse((intVolt % 65536 / 256).ToString());
            commandBuffer[5] = byte.Parse((intVolt / 65536 % 256).ToString());
            commandBuffer[6] = byte.Parse((intVolt / 65536 / 256).ToString());
            commandBuffer[25] = CheckWorker.PowerCommandsADD(commandBuffer);
            EequeueQueue(commandBuffer);
        }

        public void upVoltage()
        {
            string flag;
            if (!Port.IsOpen)
            {
                flag = "电源通信端口已被关闭，升压失败！";
                UIMessageDialog.ShowMessageDialog(flag, "升压失败", false, UIStyle.Colorful);
                return;
            }
            try
            {
                if (IsCommunityError)
                {
                    IsOpen = false;
                    IsUpDown = false;
                    flag = PowerName + "电源开启失败！";
                    UIMessageDialog.ShowMessageDialog(flag, "升压失败", false, UIStyle.Colorful);
                    return;
                }

                ButtonAction.Enabled = false;
                Label.Text = "已开启";
                ButtonAction.Text = "关闭";
                ButtonAction.Enabled = true;

                setVolt(UpStepVal);

                VoltageCurrent = 0;
                VoltageCurrent = VoltageCurrent + UpStepVal;
                Debug.WriteLine(PowerName + "开启升压至：" + VoltageCurrent);

                if (UpStepVal < VoltageValue)
                {
                    isUpDown = true;
                    double interval = (double)(UpInterval * 1000);
                    TempTime = Global.Global.PowerUpWaitTime;
                    //等一段时间
                    timerUp.Interval = interval + Global.Global.PowerUpWaitTime;
                    timerUp.Start();
                }
                else
                {
                    isUpDown = false;
                }
                foreach (var nud in NumList)
                {
                    nud.Enabled = false;
                }
                //指示灯变绿
                /*foreach (var channel in Global.Global.ChannelList)
                {
                    if (channel.VGPower.PowerName == PowerName)
                    {
                        channel.ThreeColor.EequeueCommandQueue("Green");
                        break;
                    }
                }*/
                ThreeColor.EequeueCommandQueue("Green");
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.StackTrace);
                flag = PowerName + "电源升压失败！";
                UIMessageDialog.ShowMessageDialog(flag, "升压失败", false, UIStyle.Colorful);
                return;
            }
        }

        public void TimerUpTaskLow(object source, ElapsedEventArgs e)
        {
            lock (this)
            {
                timerUp.Interval = timerUp.Interval - TempTime;
                TempTime = 0;
                decimal up;
                bool stopFlag = false;
                if (voltageCurrent + upStep < voltage)
                {
                    up = upStep;
                }
                else
                {
                    up = voltage - voltageCurrent;
                    stopFlag = true;
                }
                //设置步进升压步长
                voltageCurrent = voltageCurrent + up;
                setVolt(voltageCurrent);
                Debug.WriteLine(PowerName + "步进升压至：" + voltageCurrent);

                if (stopFlag)
                {
                    System.Threading.Thread.Sleep(1000);
                    if (RealVoltage < voltage)
                    {
                        setVolt(voltage);
                    }
                    //关闭升压计时器
                    timerUp.Enabled = false;
                    isUpDown = false;

                    if (ButtonAction != null)
                    {
                        ButtonAction.Enabled = true;
                    }
                    //this.refreshButton();
                }

            }
        }

        public void TimerDownTaskLow(object source, ElapsedEventArgs e)
        {
            lock (this)
            {
                decimal down;
                bool stopFlag = false;
                if (voltageCurrent - downStep > 0)
                {
                    down = downStep;
                }
                else
                {
                    down = voltageCurrent;
                    stopFlag = true;
                }

                //设置步进降压步长
                voltageCurrent = voltageCurrent - down;
                setVolt(voltageCurrent);

                Debug.WriteLine(PowerName + "步进降压至：" + voltageCurrent);

                if (stopFlag)
                {
                    //关闭降压计时器
                    timerDown.Enabled = false;
                    isUpDown = false;
                    //关闭电源输出
                    close();
                    isOpen = false;
                    RealVoltage = 0;
                    RealCurrent = 0;

                    if (ButtonAction != null)
                    {
                        ButtonAction.Enabled = true;
                    }
                    //this.refreshButton();
                }
            }
        }

        /// <summary>
        /// 查询电源实时输出值（电压、电流）
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timerForLowPowerRealVC_Tick(object sender, EventArgs e)
        {
            //查询电压电流
            byte[] commandBuffer = new byte[] { 0xAA, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0x0A };

            EequeueQueue(commandBuffer);
        }

        public void EequeueQueue(byte[] command)
        {
            /*lock (CommandLock)
            {
                CommandsQueue.Enqueue(command);
            }*/
            CommandsQueue.Enqueue(command);
        }
        public byte[] DequeueQueue()
        {
            /*lock (CommandLock)
            {
                if (CommandsQueue.Count > 0)
                {
                    return (byte[])CommandsQueue.Dequeue();
                }
                else
                {
                    return null;
                }
            }*/
            if (CommandsQueue.Count > 0)
            {
                return (byte[])CommandsQueue.Dequeue();
            }
            else
            {
                return null;
            }
        }

    }
}
